﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;

namespace OpcSelfHost.printer
{
    class BrPosCommand
    {
        /// <summary>
        /// 初始化打印机
        /// </summary>
        /// <returns></returns>
        public static byte[] PrinterInit() { return new byte[] { 0x1b, 0x40 }; }

        /// <summary>
        /// 文字对齐
        /// </summary>
        /// <param name="n">0、1、2 -> 左中右</param>
        /// <returns></returns>
        public static byte[] TextAligh(int n)
        {

            return new byte[] { 0x1b, 0x61, (byte)n };

        }

        /// <summary>
        /// 打印并换行
        /// </summary>
        /// <returns></returns>
        public static byte[] PrintAndLineFeed() { return new byte[] { 0x0A }; }

        /// <summary>
        /// 打印并走纸
        /// </summary>
        /// <param name="n">0 ≤ n ≤ 255</param>
        /// <returns></returns>
        public static byte[] PrintAndFeedPaper(int n)
        {
            if (n < 0 || n > 255)
            {

                n = 40;
            }

            return new byte[] { 0x1b, 0x4a, (byte)n };

        }


        public static byte[] SetLineSpacing(int n)
        {


            if (n < 0 || n > 255)
            {

                n = 40;
            }

            return new byte[] { 0x1b, 0x33, (byte)n };

        }


        public static byte[] Cutter()
        {

          

            return new byte[] { 0x1d, 0x56, 0x01 };
        }


        /// <summary>
        /// 打印二维码
        /// </summary>
        /// <param name="str">二维码内容</param>
        /// <returns></returns>
        public static byte[] QRCoeData(String str) {

            List<byte> list = new List<byte>();
            if (str.Length > 0)
            {
                //读取数据
                byte[] strData = Encoding.GetEncoding("GBK").GetBytes(str);
              
                int strDataLen = strData.Length;
                          

                  list.Add(0x1b);
                  list.Add(0x5a);
                  list.Add(0x00);
                  list.Add(0x00);
                  list.Add(0x08);//二维码大小1-8
                  list.Add((byte)(strDataLen % 256));
                  list.Add((byte)(strDataLen / 256));

                foreach(byte b in strData){

                     list.Add(b);
                
                }
                 list.Add(0x0a); 
            }
            else {//数据为空


              
               list.Add(0x0a);
            
            
            }



            return list.ToArray();
        
        }






        public static Bitmap compressBitmap(Bitmap bitmapOrg, int nWidth,
            int nHeight)
        {

           
            int width = bitmapOrg.Width;
            int height = bitmapOrg.Height;
            // 定义预转换成的图片的宽度和高度
            int newWidth = nWidth;
            int newHeight = nHeight;
            // 计算缩放率，新尺寸除原始尺寸
            float scaleWidth = ((float)newWidth) / width;
            float scaleHeight = ((float)newHeight) / height;
            // 创建操作图片用的matrix对象
            Matrix matrix = new Matrix();
            // 缩放图片动作
            matrix.Scale(scaleWidth, scaleHeight);

          
          
            Bitmap resizedBitmap = new Bitmap(bitmapOrg, newWidth, newHeight);

    
            return resizedBitmap;
        }
        private static int RGB2Gray(int R, int G, int B)
        {
            int gray = (int)(R * 0.299 + G * 0.587 + B * 0.114);
            return gray;
        }

        public static byte px2Byte(int x, int y, Bitmap bit)
        {
            byte b;
            int pixel = (bit.GetPixel(x, y)).ToArgb();
            Color pixel1 = bit.GetPixel(x, y);
            int red = (pixel & 0x00ff0000) >> 16; // 取高两位
            int green = (pixel & 0x0000ff00) >> 8; // 取中两位
            int blue = pixel & 0x000000ff; // 取低两位
            int gray = RGB2Gray(red, green, blue);
            //  Console.WriteLine("gray的值是"+gray);
            if (gray < 128)
            {
                b = 1;
            }
            else
            {
                b = 0;
            }
            return b;
        }
        //1d76打印图片
        public static byte[] Print_1D76(Bitmap bitmap, int nWidth = 0, int nHeight = 0)
        {
            if (nWidth <= 0)
            {
                nWidth = bitmap.Width;
            }

            if (nHeight <= 0)
            {

                nHeight = bitmap.Height;
            }



            Bitmap nbit = compressBitmap(bitmap, nWidth, nHeight);
            int width = nbit.Width;
            int height = nbit.Height;
            int xwidth = (width+7) / 8;


            int lineHeight = 24;
            List<Byte> list = new List<Byte>();

            
            int b = 0;
            for (int i = 0; i < height; i += lineHeight)
            {
                lineHeight = (i + lineHeight) >= height ? (height - i) : lineHeight;
               list.Add( 0x1D);
                list.Add( 0x76);
               list.Add( 0x30);
                list.Add( 0x00);//正常范围
                list.Add( (byte)(xwidth % 256));
                list.Add( (byte)(xwidth / 256));
                list.Add( (byte)(lineHeight % 256));
                list.Add( (byte)(lineHeight / 256));


                byte bit=0x00;
                for (int h2 = 0; h2 < lineHeight; h2++)
                {
                    for (int x = 0; x < (xwidth); x++)
                    {


                        for (int n = 0; n < 8; n++)
                        {
                            int h = h2 + i;
                            int w =x * 8 + n;
                            if (h >= height||w>=width)
                            {
                                b = 0;

                            }
                            else
                            {
                                b = px2Byte(w, h,nbit);
                            }
                         
                            bit = (byte)(b << (7 - n) | bit);
                        }
                        list.Add(bit);
                        bit=0x00;
                    }
                }


            }
           list.Add(0x0a);


           
            return list.ToArray();
        }




        //10.1.1 初始化打印机

        /**
         * 初始打印机，指令集复位
         *
         * @return
         */
        public static byte[] t1b40()
        {


            return new byte[] { 0x1B, 0x40 };
        }

        //10.1.2唤醒打印
        public static byte[] t00()
        {


            return new byte[] { 0x00 };
        }

        //10.1.3回车
        public static byte[] t0D()
        {


            return new byte[] { 0x0D };
        }


        //10.1.4换行
        public static byte[] t0A()
        {


            return new byte[] { 0x0A };
        }

        //10.1.5执行N点走纸
        public static byte[] t1b4a(int n)
        {


            return new byte[] { 0x1B, 0x4A, (byte)n };
        }

        //10.1.6打印并走纸到黑标处
        public static byte[] t0c()
        {


            return new byte[] { 0x0C };
        }


        //10.2.1选择字库
        public static byte[] t1b38(int n)
        {


            return new byte[] { 0x1B, 0x38, (byte)n };
        }


        //10.3.1灰度打印
        public static byte[] t1b6d(int n)
        {


            return new byte[] { 0x1B, 0x6D, (byte)n };
        }

        //10.3.2横向放大
        public static byte[] t1b55(int n)
        {


            return new byte[] { 0x1B, 0x55, (byte)n };
        }

        //10.3.3纵向放大
        public static byte[] t1b56(int n)
        {


            return new byte[] { 0x1B, 0x56, (byte)n };
        }

        //10.3.4等比例放大
        public static byte[] t1b57(int n)
        {


            return new byte[] { 0x1B, 0x57, (byte)n };
        }

        //10.3.5下划线打印
        public static byte[] t1b2d(int n)
        {


            return new byte[] { 0x1B, 0x2D, (byte)n };
        }

        //10.3.6上划线打印
        public static byte[] t1b2b(int n)
        {


            return new byte[] { 0x1B, 0x2B, (byte)n };
        }

        //10.3.7反白打印
        public static byte[] t1b69(int n)
        {


            return new byte[] { 0x1B, 0x69, (byte)n };
        }

        //10.3.8反向打印
        public static byte[] t1b63(int n)
        {


            return new byte[] { 0x1B, 0x63, (byte)n };
        }

        //10.3.9字符旋转打印
        public static byte[] t1c49(int n)
        {


            return new byte[] { 0x1C, 0x49, (byte)n };
        }

        //10.4.1设置行间距
        public static byte[] t1b31(int n)
        {


            return new byte[] { 0x1B, 0x31, (byte)n };
        }

        //10.4.2设置字符间距
        public static byte[] t1b70(int n)
        {


            return new byte[] { 0x1B, 0x70, (byte)n };
        }

        //10.4.3设置对齐方式
        public static byte[] t1b61(int n)
        {


            return new byte[] { 0x1B, 0x61, (byte)n };
        }

 

        //10.4.8设置右边距
        public static byte[] t1b51(int n)
        {


            return new byte[] { 0x1B, 0x51, (byte)n };
        }

        //10.4.9设置左边距
        public static byte[] t1b6c(int n)
        {
            return new byte[] { 0x1B, 0x6C, (byte)n };
        }

     

        //10.6一维码打印

        /**
         * 打印一维条码
         *
         * @param type 条码类型 65- UPC-A,66-UPC-E,67-EAN13,68-EAN8,69-CODE39,70-INTERLEAVED25,71-CODE BAR
         *             72-CODE93,73-CODE128
         * @param data 条码内容
         * @return 打印数据
         */
        public static byte[] t1d6b(int type, String data)
        {
            byte[] strdata = Encoding.GetEncoding("GBK").GetBytes(data);

            List<Byte> list = new List<Byte>();
            //byte[] errorData;
            int k = 0;


            list.Add( 0x1D);
            list.Add(0x6B);
            list.Add( (byte)type);
            list.Add((byte)(strdata.Length));

            foreach (byte b in strdata)
            {
                list.Add( b);
            }

            list.Add(0x0A);

            return list.ToArray();

        }

        //10.6.4HRI字符
        public static byte[] t1d48(int n)
        {
            return new byte[] { 0x1D, 0x48, (byte)n };
        }

        //10.6.5设置条码高度
        public static byte[] t1d68(int n)
        {
            return new byte[] { 0x1D, 0x68, (byte)n };
        }

        //10.6.6设置条码宽度
        public static byte[] t1d77(int n)
        {
            return new byte[] { 0x1D, 0x77, (byte)n };
        }

   
      
        //11.22加粗打印

        /**
         * 加粗打印
         *
         * @param n
         * @return
         */
        public static byte[] t1f5535(int n)
        {

            return new byte[] { 0x1F, 0x55, 0x35, (byte)n };

        }

        //11.12蜂鸣测试
        public static byte[] t1b552b(int n)
        {
            return new byte[] { 0x1B, 0x55, 0x2B, (byte)n };
        }


     

    

   
      
        public static byte[] t1d21(byte data)
        {


            return new byte[] { 0x1D, 0x21, data };


        }



    }
}
